package com.ljx.designMode.agency;



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author LJX
 * @Description: TODO
 * @Date: 2022/11/9 14:33
 * @Version 1.0
 */

/**
 * 什么是代理：对其他对象提供一种代理以控制这个对象的访问
 * 为什么需要使用代理：代理模式主要作用是为其他对象提供一种代理以控制这个对象的访问
 * 在某些情况下，一个对象不想或者不能直接引用另一个对象
 * 而代理对象可以在客户端和目标对象之间祈祷中介的作用
 */
public class JdkDynamicAgencyTest {
	public static void main(String[] args) {
		ProxyFactory proxyFactory = new ProxyFactory(new Star1());
		Film film = proxyFactory.geInstance();
		film.movie();
		film.handSome(12,12);

	}
}

interface Film{
	void movie();
	int handSome(int a,int b);
}

class Star1 implements Film{

	@Override
	public void movie() {
		System.out.println("彭于晏在演燕子李三");
	}

	@Override
	public int handSome(int a,int b) {
		System.out.println("彭于晏最帅"+a+b);
		return a+b;
	}
}

class ProxyFactory{
	private Object target;

	public ProxyFactory(Object object) {
		this.target = object;
	}

	// 获取代理对象
	public Film geInstance(){
		/**
		 * java中提供了一个代理类，该类可以动态生成代理类的对象
		 * ClassLoader classLoader:被代理类所使用的类加载器（使被代理类进行类加载）
		 * Class<?>[] interfaces:被代理类对象实现的接口
		 * InvocationHandler invocationHandler：当代理类调用代理方法时触发的函数
		 *
		 InvocationHandler 调用处理器；然后实现处理器；动态代理
		 */
		ClassLoader classLoader = target.getClass().getClassLoader();
		Class<?>[] interfaces = target.getClass().getInterfaces();
		InvocationHandler invocationHandler = new InvocationHandler() {
			// proxy被代理的类，method执行被代理对象的方法对象，args执行的方法需要的参数
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				sing();
				// 回调该方法--可以对原方法进行扩展，但是并没有修改原类的代码
				Object invoke = method.invoke(target, args);
				dance();
				return invoke;
			}
		};
		Object o = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
		return (Film) o;
	}

	public void sing(){
		System.out.println("唱歌");
	}
	public void dance(){
		System.out.println("跳舞");
	}
}

